package com.sky.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.WebSocket.WebSocketServer;
import com.sky.context.BaseContext;
import com.sky.dto.OrderPaymentDTO;
import com.sky.dto.OrderSubmitDTO;
import com.sky.entity.*;
import com.sky.enumeration.OrderSocketTypeEnum;
import com.sky.exceptionHandler.ServiceException;
import com.sky.mapper.AddressBootMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCatMapping;
import com.sky.service.OrderService;
import com.sky.vo.OrderDetailVO;
import com.sky.vo.OrderSubmitVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private AddressBootMapper addressBootMapper;

    @Autowired
    private ShoppingCatMapping shoppingCatMapping;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private WebSocketServer webSocketServer;

    @Override
    @Transactional
    public OrderSubmitVO submit(OrderSubmitDTO dto) {
        /**
         * 1. 校验是否存在对应的地址
         * 2. 校验购物车数据是否存在
         * **/
        AddressBootEntity addressBootEntity = addressBootMapper.getById(dto.getAddressBookId());
        if (addressBootEntity == null) {
            throw new ServiceException("地址不存在");
        }
        ShoppingCatEntity shoppingCatEntity = new ShoppingCatEntity();
        shoppingCatEntity.setUserId(BaseContext.getId());
        List<ShoppingCatEntity> shoppingCatEntities = shoppingCatMapping.list(shoppingCatEntity);
        if (shoppingCatEntities == null || shoppingCatEntities.size() == 0) {
            throw new ServiceException("购物车商品为空");
        }

        /**
         * 1. 向订单表中插入数据
         * 2. 向订单明细表中插入数据
         * 3. 清空购物车数据
         */
        OrderEntity orderEntity = new OrderEntity();
        BeanUtils.copyProperties(dto, orderEntity);
        orderEntity.setNumber(String.valueOf(System.currentTimeMillis()));
        orderEntity.setStatus(OrderEntity.TO_BE_PAID);
        orderEntity.setUserId(BaseContext.getId());
        orderEntity.setOrderTime(LocalDateTime.now());
        orderEntity.setPayStatus(OrderEntity.UNPAID);
        orderEntity.setPhone(addressBootEntity.getPhone());
        orderEntity.setAddress(addressBootEntity.getDetail());
        orderEntity.setConsignee(addressBootEntity.getConsignee());
        log.info("构建orderEntity数据=>{}", orderEntity);

        orderMapper.insert(orderEntity);

        ArrayList<OrderDetailEntity> orderDetailEntities = new ArrayList<>();
        for (ShoppingCatEntity catEntity : shoppingCatEntities) {
            OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
            BeanUtils.copyProperties(catEntity, orderDetailEntity);
            orderDetailEntity.setOrderId(orderEntity.getId());
            orderDetailEntities.add(orderDetailEntity);
        }
        log.info("构建 orderDetails 数据 =>{}", orderDetailEntities);

        orderDetailMapper.insertBatch(orderDetailEntities);

        // 清空购物车数据
        shoppingCatMapping.clean(BaseContext.getId());

        // 构建返回数据
        OrderSubmitVO vo = OrderSubmitVO.builder().id(orderEntity.getId()).orderAmount(orderEntity.getAmount()).orderNumber(orderEntity.getNumber())
                .orderTime(orderEntity.getOrderTime()).build();
        return vo;
    }

    @Override
    public OrderDetailVO getDetail(Long id) {
        OrderEntity orderEntityList = orderMapper.getById(id);
        log.info("查询订单数据 =>{}", orderEntityList);
        List<OrderDetailEntity> orderDetailEntityList = orderDetailMapper.getByOrderId(id);
        log.info("查询订单明细数据 =>{}", orderDetailEntityList);

        OrderDetailVO orderDetailVO = new OrderDetailVO();
        BeanUtils.copyProperties(orderEntityList, orderDetailVO);
        orderDetailVO.setOrderDetailList(orderDetailEntityList);
        return orderDetailVO;
    }

    @Override
    public List<OrderDetailVO> getHistoryOrders(Integer page, Integer pageSize, Integer status) {
        PageHelper.startPage(page, pageSize);
        OrderEntity orderEntity = OrderEntity.builder().userId(BaseContext.getId()).status(status).build();
        List<OrderEntity> orderEntities = orderMapper.pageQuery(orderEntity);
        PageInfo<OrderEntity> pageInfo = new PageInfo<>(orderEntities);
        log.info("查询历史订单数据=>{}", pageInfo.getList().get(0));
        List<OrderEntity> list = pageInfo.getList();
        ArrayList<OrderDetailVO> orderDetailVOS1 = new ArrayList<>();
        for (OrderEntity entity : list) {
            OrderDetailVO orderDetailVO = new OrderDetailVO();
            BeanUtils.copyProperties(entity, orderDetailVO);
            orderDetailVOS1.add(orderDetailVO);
        }
        log.info("历史订单数据ArrayList=>{}", orderDetailVOS1);
        List<Long> orderIds = orderDetailVOS1.stream().map(OrderDetailVO::getId).collect(Collectors.toList());
        List<OrderDetailEntity> orderDetails = orderDetailMapper.getByOrderIdWithBatch(orderIds);
        log.info("orderDetails =>{}", orderDetails);
        for (OrderDetailVO orderDetailVO : orderDetailVOS1) {
            Long id = orderDetailVO.getId();
            List<OrderDetailEntity> orderDetailEntityList = orderDetails.stream().filter(item -> item.getOrderId().equals(id)).collect(Collectors.toList());
            if (orderDetailEntityList.size() > 0) {
                orderDetailVO.setOrderDetailList(orderDetailEntityList);
            }
        }
        return orderDetailVOS1;
    }

    @Override
    public void cancel(Long id) {
        OrderEntity entity = orderMapper.getById(id);
        if (entity == null) {
            throw new ServiceException("订单不存在");
        }

        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setId(id);

        //  1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 7退款
        if (entity.getStatus() > OrderEntity.TO_BE_CONFIRMED) {
            // 需要退款 && 修改状态为退款
            orderEntity.setPayStatus(OrderEntity.REFUNDING);
        }

        orderEntity.setStatus(OrderEntity.REFUND);
        orderEntity.setCancelReason("用户取消");
        orderEntity.setCancelTime(LocalDateTime.now());
        orderMapper.update(orderEntity);
    }

    // 订单成功的回调
    public void paySuccess(String orderNumber) {
        Long userId = BaseContext.getId();
        // 根据订单号查询订单信息
        OrderEntity order = orderMapper.getOrderByNumberAndUserId(orderNumber, userId);
        if (order == null) {
            throw new ServiceException("订单不存在");
        }
        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        OrderEntity orderEntity = OrderEntity.builder().id(order.getId()).status(OrderEntity.TO_BE_CONFIRMED)
                .payStatus(OrderEntity.PAID)
                .checkoutTime(LocalDateTime.now()).build();
        orderMapper.update(orderEntity);

        HashMap<String, Object> objectHashMap = new HashMap<>();
        objectHashMap.put("type", OrderSocketTypeEnum.Order.getCode());
        objectHashMap.put("orderId", orderEntity.getId());
        objectHashMap.put("orderNumber", orderNumber);

        String jsonString = JSONObject.toJSONString(objectHashMap);

        webSocketServer.sendAllSession(jsonString);
    }

    @Override
    public void payment(OrderPaymentDTO paymentDTO) {
        // 假设订单成功

        // 触发订单成功的回调
        paySuccess(paymentDTO.getOrderNumber());
    }

    @Override
    public void repetition(Long id) {
        // 再来一单
        // 根据订单id查询订单明细表中数据，写入到购物车中
        List<OrderDetailEntity> orderDetailEntityList = orderDetailMapper.getByOrderId(id);
        if (orderDetailEntityList.size() == 0) {
            throw new ServiceException("当前订单没有菜品");
        }

        List<ShoppingCatEntity> shoppingCatEntityList = orderDetailEntityList.stream().map(item -> {
            ShoppingCatEntity entity = new ShoppingCatEntity();
            // copy时 排除掉id字段
            BeanUtils.copyProperties(item, entity, "id");
            entity.setUserId(BaseContext.getId());
            entity.setCreateTime(LocalDateTime.now());
            return entity;
        }).collect(Collectors.toList());

        shoppingCatMapping.inserttBatch(shoppingCatEntityList);
    }

    @Override
    public void reminder(Long id) {
        // 1. 先查询是否存在这个订单
        OrderEntity entity = orderMapper.getById(id);
        if (entity == null) {
            throw new ServiceException("订单不存在");
        }
        // 2. 进行Socket催单
        HashMap<String, Object> objectHashMap = new HashMap<>();
        objectHashMap.put("type", OrderSocketTypeEnum.Remind.getCode());
        objectHashMap.put("orderId", id);
        objectHashMap.put("orderNumber", entity.getNumber());

        webSocketServer.sendAllSession(JSONObject.toJSONString(objectHashMap));
    }
}
